from twisted.web.server import NOT_DONE_YET
from dopplershift.collector.exc import Http404, Http500
from dopplershift.core.containers.mediator import getMediator
from dopplershift.core.utils.jsonserializer import dumps
from dopplershift.core.utils.xmlserializer import DSXMLSerializer
from twisted.plugin import IPlugin
from dopplershift.core.plugins.interfaces import IDSPlugin
from zope.interface import implements
from webob.multidict import MultiDict
import json
DEFAULT_AUTH_COOKIE_ID = "aksjdfkjfgkdfglfdglh"

class DSHttpBackendHandler(object):
    application = "backends.handlers.http"
    name = 'default'
    implements(IPlugin, IDSPlugin) 
    __content_type__ = 'application/json'
    _db = None
    
    def configure(self, config):
        self._config = config
        self._db = getMediator().get("AppDB") 
        self._authBackend = getMediator().get("AuthBackend")
        self._authCookie = getMediator().get("AppConfig").get('http_backend_auth_cookie')
        if self._authCookie is None:
            self._authCookie = DEFAULT_AUTH_COOKIE_ID
    def __call__(self, request):
        '''
        '''
        request.ARGS = MultiDict(self._prepareHttpArgs(request.args))
        request.RESPONSE = {"content": {}}
        if 'name' == request.matched['view'] or 'application' == request.matched['view']:
            raise Http500("Incorrect action name")
        if hasattr(self, request.matched['view']):
            request.matched = request.matched
            return getattr(self, request.matched['view'])(request)
        
        raise Http404('View not found for controller')
    def _prepareHttpArgs(self, args):
        result = []
        for el in args:
            cnt = len(args[el])
            if cnt > 1:
                for val in args[el]:
                    result.append((el, val))
            elif cnt > 0:
                result.append((el, args[el][0]))
        return result
    def _render(self, request, content_type=None, as_string=False):
        print "RENDERIT"    
        if content_type is None:
            request.setHeader('Content-Type', str(self.__content_type__))
        else:
            request.setHeader('Content-Type', content_type)
        data = self._dump(request.RESPONSE)
        if as_string == False:
            request.write(data)
            request.finish()
            return
        return data
    def _dump(self, data):
        return data            

class DSJSONHttpHandler(DSHttpBackendHandler):
    def _dump(self, data):
        return dumps(data)
class DSXMLHttpHandler(DSHttpBackendHandler):
    def _dump(self, data):
        return DSXMLSerializer()(data)

def authenticate(method):
    def callback(result, request, classObj):
        try:
            request.SESSION = json.loads(result['session'])
            request.SESSION_UID = result['uid']
        except:
            pass
        
        
        method(classObj, request)
    def errback(request, classObj):
        '''
        '''
        method(request)
    def wrapper(self,request):
        request.SESSION = {}    
        request.SESSION_UID = request.getCookie(self._authCookie)
        d = self._authBackend.authenticate(request.SESSION_UID)
        d.addCallbacks(
                       callback, 
                       errback=errback, 
                       callbackArgs=[request, self], 
                       errbackArgs=[request])
        return NOT_DONE_YET
    return wrapper